#include "DXGraphics.h"


DXGraphics::DXGraphics()
{
	center = D3DXVECTOR3(0.0f, 0.0f, 0) ;	// set to the exact center of the sprite
	timeElapsed = 0.0f ;
		
	retval = 1;
	once = false;
	unit = 0;
	unitPos = 0;
	for(int i = 0; i < 64; ++i)
		sector_area[i] = 0;
}

DXGraphics::~DXGraphics( )
{
	// clean up DirectX and COM
	cleanD3D( ) ;
}

// this function initializes and prepares Direct3D for use
void DXGraphics::initD3D(HWND hWnd)
{
    m_pD3DObject = Direct3DCreate9(D3D_SDK_VERSION);    // create the Direct3D interface

	m_hWnd = hWnd ;

    D3DPRESENT_PARAMETERS d3dpp;    // create a struct to hold various device information

    ZeroMemory(&d3dpp, sizeof(d3dpp));    // clear out the struct for use
    d3dpp.Windowed = TRUE;    // program windowed, not fullscreen
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;    // discard old frames
    d3dpp.hDeviceWindow = hWnd;    // set the window to be used by Direct3D

    // create a device class using this information and the info from the d3dpp stuct
    m_pD3DObject->CreateDevice(D3DADAPTER_DEFAULT,
                      D3DDEVTYPE_HAL,
                      hWnd,
                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                      &d3dpp,
                      &m_pD3DDevice);

	D3DXCreateSprite(m_pD3DDevice, &m_pD3DSprite);    // create the Direct3D Sprite object

	D3DXCreateTextureFromFileEx(m_pD3DDevice,    // the device pointer
                                L"empty.png",    // the sprite name
                                D3DX_DEFAULT_NONPOW2,    // default width
                                D3DX_DEFAULT_NONPOW2,    // default height
                                D3DX_DEFAULT,    // no mip mapping
                                NULL,    // regular usage
                                D3DFMT_A8R8G8B8,    // 32-bit pixels with alpha
                                D3DPOOL_MANAGED,    // typical memory handling
                                D3DX_DEFAULT,    // no filtering
                                D3DX_DEFAULT,    // no mip filtering
                                D3DCOLOR_XRGB(255, 255, 255),    // the hot-pink color key
                                NULL,    // no image info struct
                                NULL,    // not using 256 colors
                                &m_pTexture[EMPTY]);    // load to sprite

	D3DXCreateTextureFromFileEx(m_pD3DDevice,    // the device pointer
                                L"ship.png",    // the sprite name
                                D3DX_DEFAULT_NONPOW2,    // default width
                                D3DX_DEFAULT_NONPOW2,    // default height
                                D3DX_DEFAULT,    // no mip mapping
                                NULL,    // regular usage
                                D3DFMT_A8R8G8B8,    // 32-bit pixels with alpha
                                D3DPOOL_MANAGED,    // typical memory handling
                                D3DX_DEFAULT,    // no filtering
                                D3DX_DEFAULT,    // no mip filtering
                                D3DCOLOR_XRGB(255, 255, 255),    // the hot-pink color key
                                NULL,    // no image info struct
                                NULL,    // not using 256 colors
                                &m_pTexture[PLAYER]);    // load to sprite

	D3DXCreateTextureFromFileEx(m_pD3DDevice,    // the device pointer
                                L"enemy.png",    // the sprite name
                                D3DX_DEFAULT_NONPOW2,    // default width
                                D3DX_DEFAULT_NONPOW2,    // default height
                                D3DX_DEFAULT,    // no mip mapping
                                NULL,    // regular usage
                                D3DFMT_A8R8G8B8,    // 32-bit pixels with alpha
                                D3DPOOL_MANAGED,    // typical memory handling
                                D3DX_DEFAULT,    // no filtering
                                D3DX_DEFAULT,    // no mip filtering
                                D3DCOLOR_XRGB(255, 255, 255),    // the hot-pink color key
                                NULL,    // no image info struct
                                NULL,    // not using 256 colors
                                &m_pTexture[ENEMY]);    // load to sprite

	D3DXCreateTextureFromFileEx(m_pD3DDevice,    // the device pointer
                                L"star.png",    // the sprite name
                                D3DX_DEFAULT_NONPOW2,    // default width
                                D3DX_DEFAULT_NONPOW2,    // default height
                                D3DX_DEFAULT,    // no mip mapping
                                NULL,    // regular usage
                                D3DFMT_A8R8G8B8,    // 32-bit pixels with alpha
                                D3DPOOL_MANAGED,    // typical memory handling
                                D3DX_DEFAULT,    // no filtering
                                D3DX_DEFAULT,    // no mip filtering
                                D3DCOLOR_XRGB(255, 255, 255),    // the hot-pink color key
                                NULL,    // no image info struct
                                NULL,    // not using 256 colors
                                &m_pTexture[STAR]);    // load to sprite

	D3DXCreateTextureFromFileEx(m_pD3DDevice,    // the device pointer
                                L"station.png",    // the sprite name
                                D3DX_DEFAULT_NONPOW2,    // default width
                                D3DX_DEFAULT_NONPOW2,    // default height
                                D3DX_DEFAULT,    // no mip mapping
                                NULL,    // regular usage
                                D3DFMT_A8R8G8B8,    // 32-bit pixels with alpha
                                D3DPOOL_MANAGED,    // typical memory handling
                                D3DX_DEFAULT,    // no filtering
                                D3DX_DEFAULT,    // no mip filtering
                                D3DCOLOR_XRGB(255, 255, 255),    // the hot-pink color key
                                NULL,    // no image info struct
                                NULL,    // not using 256 colors
                                &m_pTexture[STATION]);    // load to sprite

	D3DXCreateTextureFromFileEx(m_pD3DDevice,    // the device pointer
                                L"missile.png",    // the sprite name
                                D3DX_DEFAULT_NONPOW2,    // default width
                                D3DX_DEFAULT_NONPOW2,    // default height
                                D3DX_DEFAULT,    // no mip mapping
                                NULL,    // regular usage
                                D3DFMT_A8R8G8B8,    // 32-bit pixels with alpha
                                D3DPOOL_MANAGED,    // typical memory handling
                                D3DX_DEFAULT,    // no filtering
                                D3DX_DEFAULT,    // no mip filtering
                                D3DCOLOR_XRGB(255, 255, 255),    // the hot-pink color key
                                NULL,    // no image info struct
                                NULL,    // not using 256 colors
                                &m_pTexture[MISSILE]);    // load to sprite

	D3DXCreateFont(m_pD3DDevice,    // the m_pD3DObject Device
                   20,    // font height of 30
                   0,    // default font width
                   FW_NORMAL,    // font weight
                   1,    // not using MipLevels
                   true,    // italic font
                   DEFAULT_CHARSET,    // default character set
                   OUT_DEFAULT_PRECIS,    // default OutputPrecision,
                   DEFAULT_QUALITY,    // default Quality
                   DEFAULT_PITCH | FF_DONTCARE,    // default pitch and family
                   L"Arial",    // use Facename Arial
                   &m_pD3DFont);    // the font object

	m_menu = new Menu;
	m_menu->MenuInit(hWnd, d3dpp.BackBufferHeight, d3dpp.BackBufferWidth);

	m_player = new Player;
	bufferIn[0]= '~';

	WSAStartup(MAKEWORD(2,0), &wsaData);
	RunClient();


//TODO: FIX SPACING
	//Initialize quadrant
	//int a(0),x(50),y(40);
	//for(int i = 1; i <= MAX_COLS; ++i) //Eight columns
	//{
	//	for(int j = 1; j <= MAX_ROWS; ++j) //by eight rows
	//	{
	//		sector_area[a].x = x;
	//		sector_area[a].y = y;
	//		x += 62;
	//		a++;

	//	}
	//	x = 50;
	//	y += 62;
	//}

	return ;
}

void DXGraphics::Update( float dt )
{
	gDInput->poll( ) ;

	//temp values to hold incoming data
	static int tempx = 0;
	static int tempy = 0;
	static int missile = 0;
	static int energy = 0;
	static int shield = 0;
	static int tempsx = 0;
	static int tempsy = 0;
	m_menu->MenuInput();
	
	//send(Socket, "Hello", sizeof("Hello"), 0);

	//if(m_menu->getClick())
	if(gDInput->mouseButtonDown(0))// && bufferIn[0] == '~')
	{
		//sennd messages
		//bufferOut[0] = m_menu->GetMsgOut().click;
		//send(Socket, bufferOut, sizeof(bufferOut), 0); //Send L/R(0/1) button click
		if(!once)
		{
			if(m_menu->GetMsgOut().type != '*')
			{
				bufferOut[0] = m_menu->GetMsgOut().type;
				send(Socket, bufferOut, 1, 0); //Send quadrant/galaxy specifier

				if( m_menu->GetMsgOut().type == 'Q' || m_menu->GetMsgOut().type == 'G' )
				{
					//Wait for data from server
					//find placement
					//receives the unit type

					bufferOut[0] = m_menu->GetMsgOut().posX;
					send(Socket, bufferOut, 1, 0); //Send selection x

					bufferOut[0] = m_menu->GetMsgOut().posY;
					send(Socket, bufferOut, 1, 0); //Send selection y

					//if( m_menu->GetMsgOut().type == 'G')
					//{
					//	static int unitx = 0;
					//	static int unity = 0;

					//	for(int i = 0; i < 64; ++i)
					//	{
					//		retval = recv(Socket, bufferIn, sizeof(bufferIn), 0);
					//		unit = atoi(bufferIn);
					//		//receives position of unit type
					//		retval = recv(Socket, bufferIn, sizeof(bufferIn), 0);
					//		unitx = atoi(bufferIn);

					//		retval = recv(Socket, bufferIn, sizeof(bufferIn), 0);
					//		unity = atoi(bufferIn);

					//		unitPos = (unity*8) + unitx;
					//		sector_area[unitPos] = unit;
					//	}
					//}


					//position in the galaxy
					retval = recv(Socket, bufferIn, sizeof(bufferIn), 0);
					tempsx = atoi(bufferIn);
					retval = recv(Socket, bufferIn, sizeof(bufferIn), 0);
					tempsy = atoi(bufferIn);
					//get positions from server					//position within a quadrant
					retval = recv(Socket, bufferIn, sizeof(bufferIn), 0);
					tempx = atoi(bufferIn);
					retval = recv(Socket, bufferIn, sizeof(bufferIn), 0);
					tempy = atoi(bufferIn);



					////current missiles
					//retval = recv(Socket, bufferIn, sizeof(bufferIn), 0);
					//missile = atoi(bufferIn2);
					////current energy
					//retval = recv(Socket, bufferIn, sizeof(bufferIn), 0);
					//energy = atoi(bufferIn2);
					////current shields
					//retval = recv(Socket, bufferIn, sizeof(bufferIn), 0);
					//shield = atoi(bufferIn2);
				}
			}

			m_menu->SetClick(false);
			m_menu->m_msgOut.type = '*';
			once = true;

		}
	}
	else
	{
		if(once)
		once = false;
	}
	tempx;	tempy;
	missile;	energy;		shield;
	tempsx;	tempsy;

	//converts the x and y into a positon on a 0-63 position in a vector
	int p = (tempsy*8)+tempsx;
	int q = (tempy*8)+tempx;

	m_menu->m_msgIn.SetShip(energy,shield,missile);
	//m_menu->GetMsgIn().SetShip(energy,shield,missile);
	m_menu->m_msgIn.SetPos(tempx,tempy,tempsx,tempsy);
	//m_menu->GetMsgIn().ConvertCoords(tempx, tempy);
	//set player properties
	m_player->SetGPosition(m_menu->GetQuadPos(q));
	m_player->SetQPosition(m_menu->GetSectorPos(p));

	//m_player->SetEnergy(energy);
	//m_player->SetMissiles(missile);
	//m_player->SetShields(shield);


	if(retval == 0)
	{
		closesocket(Socket);
		MessageBox(m_hWnd, L"Connection to server lost.", L"Disconnected", 0);
		PostQuitMessage(0);
	}

}

// this is the function used to render a single frame
void DXGraphics::render_frame( )
{			
	
	D3DXMatrixIdentity( &matTransform ) ;

    m_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);

    m_pD3DDevice->BeginScene();    // begins the 3D scene

    m_pD3DSprite->Begin(D3DXSPRITE_ALPHABLEND);    // begin sprite drawing with transparent background

	//renders mapgrid
	m_menu->Render();

	if(m_menu->getGalaxy())
	{
		//transforms for player sprite
		D3DXMatrixTranslation(&spriteTranslation, m_player->GetGPosition().x, m_player->GetGPosition().y, 0.0f);
		m_pD3DSprite->SetTransform(&spriteTranslation);
		//draw player - 32 = half the sprites h/w - fix magicnumber
		m_pD3DSprite->Draw(m_pTexture[PLAYER], 0, &D3DXVECTOR3(32.0f,32.0f, 0.0f), //bg block
			0, D3DCOLOR_ARGB(255, 255, 255, 255));
	}
	else
	{
		//transforms for player sprite
		D3DXMatrixTranslation(&spriteTranslation,m_menu->GetSectorPos(unitPos).x, m_menu->GetSectorPos(unitPos).y, 0.0f);
		m_pD3DSprite->SetTransform(&spriteTranslation);
		//draw player - 32 = half the sprites h/w - fix magicnumber
		m_pD3DSprite->Draw(m_pTexture[sector_area[unitPos]], 0, &D3DXVECTOR3(32.0f,32.0f, 0.0f), //bg block
			0, D3DCOLOR_ARGB(255, 255, 255, 255));

		D3DXMatrixTranslation(&spriteTranslation, m_menu->GetSectorPos(unitPos).x, m_menu->GetSectorPos(unitPos).y, 0.0f);
		m_pD3DSprite->SetTransform(&spriteTranslation);
		m_pD3DSprite->Draw(m_pTexture[sector_area[unitPos]], 0, &D3DXVECTOR3(32.0f,32.0f, 0.0f), //bg block
			0, D3DCOLOR_ARGB(255, 255, 255, 255));
		
		D3DXMatrixTranslation(&spriteTranslation, m_menu->GetSectorPos(23).x, m_menu->GetSectorPos(23).y, 0.0f);
		m_pD3DSprite->SetTransform(&spriteTranslation);
		m_pD3DSprite->Draw(m_pTexture[sector_area[unitPos]], 0, &D3DXVECTOR3(32.0f,32.0f, 0.0f), //bg block
			0, D3DCOLOR_ARGB(255, 255, 255, 255));
		
		D3DXMatrixTranslation(&spriteTranslation, m_menu->GetSectorPos(54).x, m_menu->GetSectorPos(54).y, 0.0f);
		m_pD3DSprite->SetTransform(&spriteTranslation);
		m_pD3DSprite->Draw(m_pTexture[sector_area[unitPos]], 0, &D3DXVECTOR3(32.0f,32.0f, 0.0f), //bg block
			0, D3DCOLOR_ARGB(255, 255, 255, 255));
	
		D3DXMatrixTranslation(&spriteTranslation, m_menu->GetSectorPos(60).x, m_menu->GetSectorPos(60).y, 0.0f);
		m_pD3DSprite->SetTransform(&spriteTranslation);
		m_pD3DSprite->Draw(m_pTexture[sector_area[unitPos]], 0, &D3DXVECTOR3(32.0f,32.0f, 0.0f), //bg block
			0, D3DCOLOR_ARGB(255, 255, 255, 255));
	}

	//m_pD3DSprite->Draw(m_pTexture[PLAYER], 0, 
	//	&D3DXVECTOR3(0.0f, 0.0f, 0.0f), 
	//	&D3DXVECTOR3(0.0f, 0.0f, 0.0f),
	//	D3DCOLOR_ARGB(255,255,255,255));


	//for( int i = 0; i < MAX_SECTORS; i++ )
	//{
	//	D3DXMatrixTranslation( &spriteTranslation, sector_area[i].x, sector_area[i].y, 0.0f );	// move sprite from center
	//	m_pD3DSprite->SetTransform( &spriteTranslation ) ;
	//	m_pD3DSprite->Draw( m_pTexture[EMPTY], NULL, &center, NULL, D3DCOLOR_XRGB( 255, 255, 255 ) );	// draw the sprite
	//}
		//D3DXMatrixTranslation( &spriteTranslation, 0, 0, 0.0f );	// move sprite from center
		//m_pD3DSprite->SetTransform( &spriteTranslation ) ;
		//m_pD3DSprite->Draw( m_pTexture[EMPTY], NULL, &center, NULL, D3DCOLOR_XRGB( 255, 255, 255 ) );	// draw the sprite

	// create a RECT to contain the text
    RECT textbox;	// declare textbox variable
	GetWindowRect(m_hWnd, &textbox);
	textbox.right = textbox.right - textbox.left;
	textbox.bottom = textbox.bottom - textbox.top - 40;
	textbox.left = 0;
	textbox.top = 0;

	
    m_pD3DSprite->End();    // end sprite drawing

    m_pD3DDevice->EndScene();    // ends the 3D scene

    m_pD3DDevice->Present(NULL, NULL, NULL, NULL);   // displays the created frame on the screen
}


// cleans up Direct3D and COM
void DXGraphics::cleanD3D(void)
{
	for( int i = 0; i < MAX_TEXTURES; i++ )
		m_pTexture[i]->Release();

	m_pD3DFont->Release() ;
    m_pD3DDevice->Release();
    m_pD3DObject->Release();
	WSACleanup();

	delete m_menu;
	delete m_player;

    return;
}

void DXGraphics::RunClient()
{
	char		tempBuffer[128];
	sockaddr_in sockAddr = {0};
	bool		bSuccess = true;
	
	sockAddr.sin_family = AF_INET;
	sockAddr.sin_port = htons(4444);
	sockAddr.sin_addr.s_addr = inet_addr("127.0.0.1");

	// Create socket
	Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

	// Connect to server
	connect(Socket, reinterpret_cast<sockaddr*>(&sockAddr), sizeof(sockAddr));
}
